/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package wisimconsole;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import wiBase.WiException;
import wiBase.WiObject;
import wiBase.baseInterface.OnOutputStreamListener;
import wiBase.baseObject.Event;
import wiBase.baseObject.Node;
import wiBase.baseObject.Packet;
import wiEngine.WiEngine;
import wiView.graphics.UI.GraphForm;

/**
 *
 * @author brother
 */
public class WiSimConsole {

    boolean debug = false;
    private ConsoleFrame console;
    private OnOutputStreamListener ouputConsole = null;
    private GraphForm graphic;
    private wiEngine.WiEngine engine;
    // variable config
    private boolean traceDefault = true;
    public HashMap<String, Boolean> mapTraceEvent = null;
    public HashMap<Integer, OnOutputStreamListener> mapTraceNode = null;
    public HashMap<String, OnOutputStreamListener> mapTracePacket = null;

    public WiSimConsole() {
//	long t1 = System.currentTimeMillis();
//	ScheduledThreadPoolExecutor t = new ScheduledThreadPoolExecutor(1);
//	for (int i = 0; i < 300000; i++) {
//	    t.schedule(new Runnable() {
//		@Override
//		public void run() {
//		    try {
//			Thread.sleep(10000);
//		    } catch (InterruptedException ex) {
//		    }
//		}
//	    }, 10, TimeUnit.NANOSECONDS);
//	}
//	long t2 = System.currentTimeMillis();
//	System.out.println("t2:----" + (t2));
//	System.out.println("time:----" + (t2 - t1));

	if (debug) {
	    return;
	}
	console = new ConsoleFrame(this);
	engine = WiEngine.getInstance();
	graphic = new GraphForm();
//	graphic.setConsole(this);
//	engine.addOnDrawerListener(graphic.getDrawer());
	engine.addEngineControlListener(console);

	initComponent();

	console.setVisible(true);
	ouputConsole = console;

	// load libC
	//hello.jni.HelloWorld lib=new HelloWorld(null);
    }

    public WiSimConsole(GraphForm drawListener, OnOutputStreamListener consoleListener) {
	console = new ConsoleFrame(this);
	engine = WiEngine.getInstance();
	graphic = drawListener;
//	graphic.setConsole(this);
	engine.addOnDrawerListener(drawListener.getDrawer());
	engine.addEngineControlListener(console);

	ouputConsole = console;
	initComponent();
    }

    private void initComponent() {
	mapTraceEvent = new HashMap<>();
	mapTraceNode = new HashMap<>();
	mapTracePacket = new HashMap<>();

	mapTraceEvent.put("send", traceDefault);
	mapTraceEvent.put("forward", traceDefault);
	mapTraceEvent.put("receive", traceDefault);
	mapTraceEvent.put("move", traceDefault);
	mapTraceEvent.put("sleep", traceDefault);
	mapTraceEvent.put("wake", traceDefault);
	mapTraceEvent.put("drop", traceDefault);
	mapTraceEvent.put("broastcast", traceDefault);
    }

    public void initConsole() {
    }

    public void setTraceEvent(String type, boolean isOn) {
	mapTraceEvent.put(type, isOn);
    }

    public void setTraceEvent() {
	boolean eSend = mapTraceEvent.get("send");
	boolean eReceive = mapTraceEvent.get("receive");
	boolean eForward = mapTraceEvent.get("forward");
	boolean eMove = mapTraceEvent.get("move");
	boolean eSleep = mapTraceEvent.get("sleep");
	boolean eWake = mapTraceEvent.get("wake");
	boolean eDrop = mapTraceEvent.get("drop");
	boolean eBroastcast = mapTraceEvent.get("broastcast");

	engine.addTraceEvent("send", null);
	engine.addTraceEvent("receive", null);
	engine.addTraceEvent("forward", null);
	engine.addTraceEvent("move", null);
	engine.addTraceEvent("sleep", null);
	engine.addTraceEvent("wake", null);
	engine.addTraceEvent("drop", null);
	engine.addTraceEvent("broastcast", null);

	if (eSend) {
	    engine.addTraceEvent("send", ouputConsole);
	}
	if (eReceive) {
	    engine.addTraceEvent("receive", ouputConsole);
	}
	if (eForward) {
	    engine.addTraceEvent("forward", ouputConsole);
	}
	if (eMove) {
	    engine.addTraceEvent("move", ouputConsole);
	}
	if (eSleep) {
	    engine.addTraceEvent("sleep", ouputConsole);
	}
	if (eWake) {
	    engine.addTraceEvent("wake", ouputConsole);
	}
	if (eDrop) {
	    engine.addTraceEvent("drop", ouputConsole);
	}
	if (eBroastcast) {
	    engine.addTraceEvent("broastcast", ouputConsole);
	}

    }

    public void addTraceNodeToMap(int idNode, OnOutputStreamListener listener) throws WiException {
	mapTraceNode.put(idNode, listener);
    }

    public void addTraceNode() throws WiException {
	for (WiObject object : engine.getListNodes()) {
	    Node node = (Node) object;
	    if (mapTraceNode.containsKey(node.id)) {
		engine.addTraceNode(node.id, mapTraceNode.get(node.id));
	    }
	}
    }

//    public void addTracePacket(int idPacket, OnOutputStreamListener listener) throws WiException {
//	mapTraceNode.put(idPacket, listener);
//
//	engine.addTraceNode(idPacket, listener);
//    }
    public void addTracePacketToMap(String type, OnOutputStreamListener listener) {
	mapTracePacket.put(type, listener);
    }

    public void addTracePacket() throws WiException {
	for (WiObject object : engine.getListPackets()) {
	    // broastcast
//	    engine.addTracePacket(Integer.valueOf(((Packet)object).id), ouputConsole);

	    if (((Packet) object).sourceId.equals("-1") || ((Packet) object).destId.equals("-1")) {
		engine.addTracePacket(Integer.valueOf(((Packet) object).id), mapTracePacket.get("broastcast"));
	    }
	}
//	ArrayList<WiObject> lst=engine.getListPackets();
//	System.out.print(lst.size());
	for (WiObject object : engine.getListAllEvents(-1, -1)) {
	    Event event = (Event) object;
	    // dropped
	    String type = event.type;
	    if (type.equals("drop")) {
		int packetId = Integer.valueOf(event.packetId);
		engine.addTracePacket(packetId, mapTracePacket.get(type));
	    } // forward
	    else if (type.equals("forward")) {
		int packetId = Integer.valueOf(event.packetId);
		engine.addTracePacket(packetId, mapTracePacket.get(type));
	    } // normal
	    else {
		if (event.packetId == null || event.packetId.equals("")) {
		    continue;
		}
		int packetId = Integer.valueOf(event.packetId);
		engine.addTracePacket(packetId, mapTracePacket.get("normal"));
	    }
	}
    }
    // get set

    public void parse() throws WiException {
	this.engine.parse();
	ArrayList<wiBase.baseObject.Node> nodes = new ArrayList<>();
	for (wiBase.WiObject node : getEngine().getListNodes()) {
	    nodes.add((wiBase.baseObject.Node) node);
	}
	graphic.getDrawer().DrawNodes(nodes);
//	try {
//	    graphic.Start();
//	} catch (Exception ex) {
//	    ex.printStackTrace();
//	}
    }

    public WiEngine getEngine() {
	return engine;
    }

    public GraphForm getGraphic() {
	return graphic;
    }

    public ConsoleFrame getConsole() {
	return console;
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
	try {
	    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
	    //UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
	} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
	}
	WiSimConsole wiSimConsole = new WiSimConsole();
    }
    // Override
}
